package cn.xaut.ocr3.utils;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

public class OcrThreadPoolExecutor {


    private final ThreadPoolExecutor executor;

    public OcrThreadPoolExecutor() {
        int corePoolSize = Runtime.getRuntime().availableProcessors();
        int maxPoolSize = corePoolSize * 2;
        long keepAliveTime = 60L;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);

        this.executor = new ThreadPoolExecutor(
                corePoolSize,
                maxPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                new OcrThreadFactory("OCR"),
                new OcrRejectedExecutionHandler()
        );

        executor.prestartAllCoreThreads();
    }

    public Future<String> submitTask(Callable<String> task) {
        System.out.println("当前线程池状态：" + executor.toString());
        return executor.submit(task);
    }

    public void printPoolStatus() {
        System.out.println("=== Thread Pool Status ===");
        System.out.println("Core Pool Size: " + executor.getCorePoolSize());
        System.out.println("Pool Size: " + executor.getPoolSize());
        System.out.println("Active Count: " + executor.getActiveCount());
        System.out.println("Completed Task Count: " + executor.getCompletedTaskCount());
        System.out.println("Task Count: " + executor.getTaskCount());
        System.out.println("Queue Size: " + executor.getQueue().size());
        System.out.println("=========================");
    }

    public void shutdown() {
        executor.shutdown();
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdown();
                if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                    System.out.println("Pool did not terminate");
                }
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }

    public void shutdownNow() {
        executor.shutdownNow();
    }

    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                         long timeout, TimeUnit unit)
            throws InterruptedException {
        System.out.println("当前线程池状态：" + executor.toString());
        return executor.invokeAll(tasks, timeout, unit);
    }

    private static class OcrThreadFactory implements ThreadFactory {
        private final AtomicLong threadIndex = new AtomicLong(0);
        private final String threadNamePrefix;

        public OcrThreadFactory(String threadNamePrefix) {
            this.threadNamePrefix = threadNamePrefix;
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setName(threadNamePrefix + threadIndex.incrementAndGet());
            thread.setDaemon(false);
            return thread;
        }
    }

    private static class OcrRejectedExecutionHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            System.out.println("OcrThreadPoolExecutor: " + r.toString() + " rejected");
            throw new RejectedExecutionException("ocr" + r.toString() + "rejected from" + executor.toString());
        }
    }
}
